package com.headcaselabs.lb.client;

import java.io.IOException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import com.headcaselabs.lb.common.Director;

/* 
Copyright 2007, HeadCase Humanufacturing, Inc.

	Licensed under the Apache License, Version 2.0 (the "License"); you
	may not use this file except in compliance with the License. You may
	obtain a copy of the License at
	
	   http://www.apache.org/licenses/LICENSE-2.0
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
	implied. See the License for the specific language governing
	permissions and limitations under the License.
*/
/**
 * Allows controlling (currently only adding) a node to the director
 * @author Florian Leibert
 */
public class NodeRegistration  {

		private Director														director;
	
	/**
	 * Default constructor
	 * @param port to which the Director is bound
	 * @throws RemoteException
	 */
	protected NodeRegistration(int port) throws RemoteException {
		try {
			Registry registry = LocateRegistry.getRegistry(port);
			director = (Director) registry.lookup("Director");
		} catch (NotBoundException nbe) {

			nbe.printStackTrace();
			System.exit(1);
		}
	}
	
	/**
	 * Registers a node with the director
	 * @param mode
	 * @param groupName
	 * @param arg
	 * @param hostname
	 * @throws RemoteException
	 */
	public void register(String mode, String groupName, String arg, String hostname) throws RemoteException  {
		director.addNode(mode, groupName, arg, hostname);
	}
	

	//TODO: wrap around Log4J & take care of log levels
	public void log(String toLog, int level) {
		//System.out.println(toLog);
		//System.err.println(toLog);
	}

	@SuppressWarnings("static-access")
	public static void main(String[] args) throws IOException {
		int port = Director.PORT;
		HelpFormatter formatter = new HelpFormatter();
		String group = null, type = null, host = null, arg = null;
		//TODO: allow specifying more launch arguments
		if (args.length>0) {
			Options options = new Options();
			options.addOption(OptionBuilder.withArgName("port").hasArg().withDescription("port of the RMI registry").create("p"));
			options.addOption(OptionBuilder.withArgName("group").hasArg().withDescription("the loadbalancer group for this record").isRequired(true).create("g"));
			options.addOption(OptionBuilder.withArgName("type").hasArg().withDescription("either CNAME or A").isRequired(true).create("t"));
			options.addOption(OptionBuilder.withArgName("ip").hasArg().withDescription("the ip").create("ip"));
			options.addOption(OptionBuilder.withArgName("hostname").hasArg().withDescription("the hostname identifier of the new node").isRequired().create("h"));
			options.addOption(OptionBuilder.withArgName("fqdn").hasArg().withDescription("the fully qualified domain name").create("fqdn"));
			
			options.addOption("help",true,"this message");
			try {
				CommandLineParser parser = new GnuParser();
				CommandLine cmd = parser.parse( options, args);
				if (cmd.hasOption("p")) {
					port = Integer.parseInt(cmd.getOptionValue("p"));
				} 
				if (cmd.hasOption("help")) {
					formatter.printHelp("PowerPipe",options);
					System.exit(0);
				}
				group = cmd.getOptionValue("g");
				type = cmd.getOptionValue("t");
				host = cmd.getOptionValue("h");
				if (type.toUpperCase().equals("A")) {
					if (!cmd.hasOption("ip")) {
						System.out.println("Error: Expecting an ip address.");
						System.exit(1);
					}
					arg = cmd.getOptionValue("ip");
				}
				if (type.toUpperCase().equals("CNAME")) {
					if (!cmd.hasOption("fqdn")) {
						System.out.println("Error: Expecting fqdn.");
						System.exit(1);
					}
					arg = cmd.getOptionValue("fqdn");
				}
			} catch (ParseException pe) {
				 System.err.println( "Invalid parameters.  Reason: " + pe.getMessage() );
				 formatter.printHelp("NodeRegistration",options);
				 System.exit(1);
			}
		}
		NodeRegistration rn = new NodeRegistration(port);
		System.out.println("Registering node with Director:"+group+" , "+type+" , "+arg+" , "+host);
		rn.register(group, type, arg, host);
		
	}
	
	

	
}